# -*- coding: utf-8 -*-
import copy
import datetime
from pymongo import MongoClient, UpdateOne
from pymongo.errors import DuplicateKeyError
from traceback import format_exc

from energyahead.items import DataSupply
from zc_core.model.items import *
from zc_core.util.batch_gen import batch_to_year
from zc_core.model.items import ItemData, Sku
from energyahead.utils.cat_helper import CatalogHelper


class CatalogCompletePipeline(object):

    def __init__(self):
        self.helper = CatalogHelper()

    def process_item(self, item, spider):
        # 过滤条件
        if isinstance(item, ItemData) or isinstance(item, Sku):
            # 自动填充
            return self.helper.fill(item)

        return item

    def close_spider(self, spider):
        _ = spider
        self.helper.close()


class EnergyaheadPipeline(object):

    def __init__(self, mongo_uri, bot_name):
        self.mongo_uri = mongo_uri
        self.bot_name = bot_name
        self.client = None
        self.db_map = dict()

    @classmethod
    def from_crawler(cls, crawler):
        settings = crawler.settings
        return cls(
            mongo_uri=settings.get('MONGODB_URI'),
            bot_name=settings.get('BOT_NAME')
        )

    def open_spider(self, spider):
        _ = spider
        self.client = MongoClient(self.mongo_uri)
        # 默认初始化当前年的库
        year = str(datetime.datetime.now().year)
        self.db_map[year] = self.client['{}_{}'.format(self.bot_name, year)]

    def get_db(self, batch_no=None, year=None):
        if not batch_no and not year:
            raise Exception('批次编号与年份至少指定一个')
        if not year:
            year = batch_to_year(batch_no)
        db = self.db_map.get(year)
        if not db:
            db = self.client['{}_{}'.format(self.bot_name, year)]
            self.db_map[year] = db

        return db

    def close_spider(self, spider):
        _ = spider
        self.client.close()

    def process_item(self, item, spider):
        try:
            if not item:
                raise DropItem("drop empty item:  [{}]".format(self))

            if isinstance(item, Box) and item.validate():
                batch_no = item.get('batchNo')
                data_list = item.get('data')
                # order json
                if item.get('tag') == 'order_json':
                    bulk_list = list()
                    for data in data_list:
                        data['genTime'] = datetime.datetime.utcnow()
                        bulk_list.append(UpdateOne({'_id': data.get("_id")}, {'$set': data}, upsert=True))
                    self.get_db(batch_no)['order_json'].bulk_write(bulk_list, ordered=False, bypass_document_validation=True)
                    return item
                elif item.get('tag') == 'no_match_order_item':
                    bulk_list = list()
                    for data in data_list:
                        data['genTime'] = datetime.datetime.utcnow()
                        bulk_list.append(UpdateOne({'_id': data.get("_id")}, {'$set': data}, upsert=True))
                    self.get_db(batch_no)['no_match_order_item'].bulk_write(bulk_list, ordered=False, bypass_document_validation=True)
                    return item
            # 商品数据（补充）[只更新不插入]
            elif isinstance(item, DataSupply):
                if item.validate():
                    batch_no = item.get('batchNo')
                    item['_id'] = item.pop("skuId")
                    # 保存商品数据
                    self.get_db(batch_no)['item_data_pool'].update({'_id': item['_id']}, {'$set': item}, upsert=False)
                    item['skuId'] = item.pop("_id")
                    return item
        except DuplicateKeyError:
            spider.logger.debug('duplicate key error collection')
        except Exception as e:
            _ = e
            spider.logger.error(format_exc())
        return item
